package com.ocm.burnningstar.Utils;

import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Environment;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;

import java.io.File;
import java.io.FileOutputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * UncaughtException处理类,当程序发生Uncaught异常的时候,由该类来接管程序,并记录发送错误报告.
 *
 */

public class CrashHandler<T> implements Thread.UncaughtExceptionHandler {
    public static final String TAG = "CrashHandler";

    //系统默认的UncaughtException处理类
    private Thread.UncaughtExceptionHandler mDefaultHandler;
    //CrashHandler实例
    private static CrashHandler INSTANCE = new CrashHandler();
    //程序的Context对象
    private Context mContext;
    //用来存储设备信息和异常信息
    private Map<String, String> infos = new HashMap<String, String>();
    final String OOM = "java.lang.OutOfMemoryError";
    //用于格式化日期,作为日志文件名的一部分
    Class<T> initClass;

    /**
     * 保证只有一个CrashHandler实例
     */
    private CrashHandler() {
    }

    /**
     * 获取CrashHandler实例 ,单例模式
     */
    public static CrashHandler getInstance() {
        return INSTANCE;
    }

    /**
     * 初始化
     *
     * @param context
     * @param initClass  跳转Activity
     */
    public void init(Context context,Class<T> initClass) {
        mContext = context;
        this.initClass = initClass;
        //获取系统默认的UncaughtException处理器
        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
        //设置该CrashHandler为程序的默认处理器
        Thread.setDefaultUncaughtExceptionHandler(this);
    }

    /**
     * 当UncaughtException发生时会转入该函数来处理
     */
    @Override
    public void uncaughtException(Thread thread, Throwable ex) {
        final String crashReport = getCrashReport(mContext, ex);
        PendingIntent intent = PendingIntent.getActivity(mContext, 0,
                new Intent(mContext, initClass), PendingIntent.FLAG_UPDATE_CURRENT);//设置默认启动的Activity
        //休眠两秒完成提示后退出
        new Thread() {
            @Override
            public void run() {
                Looper.prepare();
                 File file = save2File(crashReport);
                Toast.makeText(mContext, "程序异常，正在重启.", Toast.LENGTH_LONG).show();
                Looper.loop();
            }
        }.start();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            Log.e(TAG, "error : ", e);
        }
        System.exit(2);
    }

    private File save2File(String crashReport) {
        //用于格式化日期,作为日志文件名的一部分
        DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        String time = dateFormat.format(new Date());
        String fileName = "crash-" + time +"-" + System.currentTimeMillis() + ".txt";
        if (Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED)) {
            try {
                //存储路径，是sd卡的crash文件夹
                File dir = new File(Environment.getExternalStorageDirectory()
                        .getAbsolutePath() + File.separator + "crash");
                if (!dir.exists())
                    dir.mkdir();
                Log.i("未捕获异常",crashReport.toString());
                File file = new File(dir, fileName);
                FileOutputStream fos = new FileOutputStream(file);
                fos.write(crashReport.toString().getBytes());
                fos.close();
                return file;
            } catch (Exception e) {
                //sd卡存储，记得加上权限，不然这里会抛出异常
                Log.i("","Show,save2File error: "+e.getMessage());
            }
        }
        return null;
    }

    /**
     * 获取APP崩溃异常报告
     *
     * @param ex
     * @return
     */
    private String getCrashReport(Context context, Throwable ex) {
        PackageInfo pinfo = getPackageInfo(context);
        StringBuffer exceptionStr = new StringBuffer();
        exceptionStr.append("Version:  "+ pinfo.versionName + "("
                + pinfo.versionCode+")\r\n"
        );
        exceptionStr.append("Android:  "+ android.os.Build.VERSION.RELEASE
                +"(" + android.os.Build.MODEL + ")\n\r"
        );
        exceptionStr.append("Exception:  "+ ex.getMessage() +
        ")\n\r");
        StackTraceElement[] elements = ex.getStackTrace();
        for (int i = 0; i < elements.length; i++) {
            exceptionStr.append(elements[i].toString()+"\n\r");
        }
        return exceptionStr.toString();
    }

    /**
     * 获取App安装包信息
     *
     * @return
     */
    private PackageInfo getPackageInfo(Context context) {
        PackageInfo info = null;
        try {
            info = context.getPackageManager().getPackageInfo(
                    context.getPackageName(), 0);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace(System.err);
        }
        if (info == null)
            info = new PackageInfo();
        return info;
    }

}
//public class CrashHandler implements UncaughtExceptionHandler {
    // 系统默认的UncaughtException处理类
//    private Thread.UncaughtExceptionHandler mDefaultHandler;
//    // CrashHandler实例
//    private static CrashHandler INSTANCE;
//    // 程序的Context对象
//    private Context mContext;
//    //保证只有一个CrashHandler实例
//    private CrashHandler() {
//
//    }
//
//    //获取CrashHandler实例 ,单例模式
//    public static CrashHandler getInstance() {
//        if (INSTANCE == null)
//            INSTANCE = new CrashHandler();
//        return INSTANCE;
//    }
//
//    /**
//     * 初始化
//     *
//     * @param context
//     */
//    public void init(Context context) {
//        mContext = context;
//        // 获取系统默认的UncaughtException处理器
//        mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
//        // 设置该CrashHandler为程序的默认处理器
//        Thread.setDefaultUncaughtExceptionHandler(this);
//    }
//
//    /**
//     * 当UncaughtException发生时会转入该重写的方法来处理
//     */
//    public void uncaughtException(Thread thread, Throwable ex) {
//        if (!handleException(ex) && mDefaultHandler != null) {
//            // 如果自定义的没有处理则让系统默认的异常处理器来处理
//            mDefaultHandler.uncaughtException(thread, ex);
//        }
//    }
//
//    /**
//     * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成.
//     *
//     * @param ex
//     *            异常信息
//     * @return true 如果处理了该异常信息;否则返回false.
//     */
//    public boolean handleException(Throwable ex) {
//        if (ex == null || mContext == null)
//            return false;
//        final String crashReport = getCrashReport(mContext, ex);
//        new Thread() {
//            public void run() {
//                Looper.prepare();
//                File file = save2File(crashReport);
//                Looper.loop();
//            }
//
//        }.start();
//        return true;
//    }
//    private File save2File(String crashReport) {
//        //用于格式化日期,作为日志文件名的一部分
//        DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
//        String time = dateFormat.format(new Date());
//        String fileName = "crash-" + time +"-" + System.currentTimeMillis() + ".txt";
//        if (Environment.getExternalStorageState().equals(
//                Environment.MEDIA_MOUNTED)) {
//            try {
//                //存储路径，是sd卡的crash文件夹
//                File dir = new File(Environment.getExternalStorageDirectory()
//                        .getAbsolutePath() + File.separator + "crash");
//                if (!dir.exists())
//                    dir.mkdir();
//                File file = new File(dir, fileName);
//                FileOutputStream fos = new FileOutputStream(file);
//                fos.write(crashReport.toString().getBytes());
//                fos.close();
//                return file;
//            } catch (Exception e) {
//                //sd卡存储，记得加上权限，不然这里会抛出异常
//                Log.i("","Show,save2File error: "+e.getMessage());
//            }
//        }
//        return null;
//    }
//
//    /**
//     * 获取APP崩溃异常报告
//     *
//     * @param ex
//     * @return
//     */
//    private String getCrashReport(Context context, Throwable ex) {
//        PackageInfo pinfo = getPackageInfo(context);
//        StringBuffer exceptionStr = new StringBuffer();
//        exceptionStr.append("Version:  "+ pinfo.versionName + "("
//                + pinfo.versionCode+")\r\n"
//        );
//        exceptionStr.append("Android:  "+ android.os.Build.VERSION.RELEASE
//                +"(" + android.os.Build.MODEL + ")\n\r"
//        );
//        exceptionStr.append("Exception:  "+ ex.getMessage() +
//        ")\n\r");
//        StackTraceElement[] elements = ex.getStackTrace();
//        for (int i = 0; i < elements.length; i++) {
//            exceptionStr.append(elements[i].toString()+"\n\r");
//        }
//        return exceptionStr.toString();
//    }
//
//    /**
//     * 获取App安装包信息
//     *
//     * @return
//     */
//    private PackageInfo getPackageInfo(Context context) {
//        PackageInfo info = null;
//        try {
//            info = context.getPackageManager().getPackageInfo(
//                    context.getPackageName(), 0);
//        } catch (NameNotFoundException e) {
//            e.printStackTrace(System.err);
//        }
//        if (info == null)
//            info = new PackageInfo();
//        return info;
//    }

//}